package mse.tx.arch.pipes;

import java.util.Properties;

import org.junit.Test;

/******************************************************************************************************************
 * File: TestPlumber.java
 * Project: Assignment 1
 * Author: Young-Suk
 *
 * Description:
 *
 *
 ******************************************************************************************************************/
public class TestPlumber
{
	public static void main( String argv[])
	{
		TestPlumber instance = new TestPlumber();
		instance.testSplitFilter();
	}

	// [ysahn] This is the test that works!!
	// @Test annotation "marks" this method as a Test Case, JUnit uses for testing.
	
	/**
	 * This function constructs a pipe-and-filter composed of 4 pipes:
	 * Source (file reader) filter -> Split filter -> normal sink & rected sink filters.
	 * 
	 * The flow of the logic is as follows:
	 *
	 *	Step 1: Instantiate the filters 
	 *
	 *	Step 2: Connect the filters. Start with the sink and work backward to the source. 
	 *
	 *	Step 3: Start the filters using the start() method.
	 *
	 *  Step 4: Join (wait) all the threads.
	 *
	 */

	@Test
	public  void testSplitFilter() {
		System.out.println("testSplitFilter");

		// [ysahn] Here the SourceFilter is are FileReader
		FileReaderSourceFilter sourceFilter = new FileReaderSourceFilter();	
		// [ysahn] setFilename is the input file to read and send. It can also be configured thru setConfiguration(Properties)
		sourceFilter.setFilename("D:\\entities\\edu.cmu\\2011-spring\\c-Architecture\\Assignements\\assignment\\A1\\A1-2011\\Sample1\\FlightData.dat");

		// [ysahn] The MergeSplit Filter is a sample filter that reads from a filter and send data to two ports: normal and rejected
		// NOTE: The merging of input has not been implemented yet.
		MergeSplitTestFilter splitFilter = new MergeSplitTestFilter();	// This is a standard filter - see FilterTemplate.java
		// [ysahn] The properties can be used to set Configuration
		Properties props = new Properties();
		props.setProperty("splitThreshold", "2.0");
		props.setProperty("normal-portid", "normal");
		props.setProperty("rejected-portid", "rejected");
		
		// [ysahn] Sending null to the configuraiton will create default "normal" and "rejected" output ports.
		splitFilter.setConfiguration(props);// config setting the ports

		// [ysahn] Following line creates the sink filter that outputs normal data
		MultiInputDataWriterSinkFilter normalSinkFilter = new MultiInputDataWriterSinkFilter();		// This is a sink filter - see SinkFilterTemplate.java
		normalSinkFilter.setFilename("D:\\entities\\edu.cmu\\2011-spring\\c-Architecture\\Assignements\\assignment\\A1\\normal.txt");
		
		// [ysahn] Following line creates the sink filter that outputs rejected data
		MultiInputDataWriterSinkFilter rejectedSinkFilter = new MultiInputDataWriterSinkFilter();		// This is a sink filter - see SinkFilterTemplate.java
		rejectedSinkFilter.setFilename("D:\\entities\\edu.cmu\\2011-spring\\c-Architecture\\Assignements\\assignment\\A1\\rejected.txt");

		/****************************************************************************
		 * Here we connect the filters starting with the sink filter 
		 ****************************************************************************/

		System.out.println("Connected");
		// [ysahn] Connects the Split filter to the source (file reader) filter
		// Notice that the connect is small caps. It is overriden function with two
		splitFilter.connect(sourceFilter, null); // This essentially says, "connect Filter3's input port to Filter2's output port
		
		// [ysahn] Connects the sink filters, one for normal and the other for rejected.
		normalSinkFilter.connect(splitFilter, "normal");// This essentially says, "connect Filter3's input port to Filter2's output port of name "normal"
		rejectedSinkFilter.connect(splitFilter, "rejected"); // This essentially says, "connect Filter3's input port to Filter2's output port

		/****************************************************************************
		 * Here we start the filters up.
		 ****************************************************************************/

		System.out.println("source started");
		sourceFilter.start();
		
		System.out.println("Split started");
		splitFilter.start();

		System.out.println("sink started");
		normalSinkFilter.start();
		rejectedSinkFilter.start();


		/****************************************************************************
		 * [ysahn] Here we wait for all the threads (not sure if it's really needed.
		 * Somehow the sample provided by the faculty works without the need of 
		 * joining the thread (???)
		 ****************************************************************************/
		try {
			sourceFilter.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			splitFilter.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			normalSinkFilter.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			rejectedSinkFilter.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("terminated");

	} // test

	
	// [ysahn] Another simple test. 
	//
	@Test
	public  void testSimpleFilters() {
		/****************************************************************************
		 * Here we instantiate three filters.
		 ****************************************************************************/

		FileReaderSourceFilter sourceFilter = new FileReaderSourceFilter();	// This is a source filter - see SourceFilterTemplate.java
		sourceFilter.setFilename("D:\\entities\\edu.cmu\\2011-spring\\c-Architecture\\Assignements\\assignment\\A1\\A1-2011\\Sample1\\FlightData.dat");
		//MiddleFilter Filter2 = new MiddleFilter();	// This is a standard filter - see FilterTemplate.java
		DefaultDataWriterSinkFilter sinkFilter = new DefaultDataWriterSinkFilter();		// This is a sink filter - see SinkFilterTemplate.java
		sinkFilter.setFilename("D:\\entities\\edu.cmu\\2011-spring\\c-Architecture\\Assignements\\assignment\\A1\\test.txt");

		/****************************************************************************
		 * Here we connect the filters starting with the sink filter (Filter 1) which
		 * we connect to Filter2 the middle filter. Then we connect Filter2 to the
		 * source filter (Filter3). You must connect filters starting with the sink
		 * filter and working your way back to the source as shown here.
		 ****************************************************************************/

		System.out.println("Connected");
		sinkFilter.Connect(sourceFilter); // This esstially says, "connect Filter3's input port to Filter2's output port

		/****************************************************************************
		 * Here we start the filters up.
		 ****************************************************************************/

		System.out.println("source started");
		sourceFilter.start();

		System.out.println("skink started");
		sinkFilter.start();


		System.out.println("terminated");

	} // test

} // PlumberTemplate